package util;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public final class DateUtil {

    private static SimpleDateFormat dateformater;

    static SimpleDateFormat sdfShort = new SimpleDateFormat("yyyyMMdd");
    static SimpleDateFormat sdfLong = new SimpleDateFormat("yyyy-MM-dd");
    static SimpleDateFormat sdfLongTime = new SimpleDateFormat("yyyyMMddHHmmss");
    static SimpleDateFormat sdfLongTimePlus = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    static SimpleDateFormat sdfLongTimePlusMill = new SimpleDateFormat("yyyyMMddHHmmssSSSS");
    private static long DAY_IN_MILLISECOND = 0x5265c00L;

    /**
     * @return long    返回类型
     * @Title: getTimeStamp
     * @Description: 获取当前系统时间的毫秒数
     * @author Illidan
     * @date 2016年5月11日 上午10:29:02
     */
    public static long getTimeStamp() {
        return System.currentTimeMillis();
    }

    /**
     * @return String    返回类型
     * @Title: dateToStr
     * @Description: 日期转换成制定格式的字符串类型
     * @author Illidan
     * @date 2016年5月11日 上午10:30:42
     */
    public static String dateToStr(Date date, String format) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            return sdf.format(date);
        } catch (Exception e) {

            return null;
        }
    }


    /**
     * @param strDate 型如 "yyyy-M-dd" 的日期字符串
     * @return 转换后的java.util.Date对象；转换失败返回null
     * @Title: parseDate
     * @Description: 把字符型日期表达式转换成java.util.Date
     * @author Illidan
     * @date 2016年5月11日 上午10:48:09
     */
    public static Date parseDate(String strDate) {
        Date date = null;
        try {
            date = getDateFormater().parse(strDate);
        } catch (Exception ex) {
            // System.err.println(ex.getMessage());
        }
        return date;
    }


    /**
     * @return Date    返回类型
     * @Title: parseDate
     * @Description: 字符串转换成制定类型的java.util.date类型
     * @author Illidan
     * @date 2016年5月11日 上午10:49:07
     */
    public static Date parseDate(String strDate, String formate) {
        Date date = null;
        try {
            date = new SimpleDateFormat(formate).parse(strDate);
        } catch (Exception ex) {
            // System.err.println(ex.getMessage());
        }
        return date;
    }

    private static DateFormat getDateFormater() {
        if (dateformater == null)
            dateformater = new SimpleDateFormat("yyyy-M-dd");
        return dateformater;
    }

    /**
     * @return Date    返回类型
     * @Title: dateAddDays
     * @Description: 指定日期加指定的天数
     * @author Illidan
     * @date 2016年5月11日 上午10:50:44
     */
    public static Date dateAddDays(Date date, int days) {
        long now = date.getTime() + (long) days * DAY_IN_MILLISECOND;
        return new Date(now);
    }

    /**
     * @return String    返回字符串类型
     * @Title: getStringOfFirstDayInMonth
     * @Description: 获取当月的第一天
     * @author Illidan
     * @date 2016年5月11日 上午11:20:32
     */
    public static String getStringOfFirstDayInMonth() {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        String temp = sdf.format(date);
        String firstDayInMoth = "";
        firstDayInMoth = temp + "-01";

        return firstDayInMoth;

    }

    public static void main(String[] args) throws ParseException {
        //Date data = getPreDateForMinutes(new Date(),1000);
        //System.out.print(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(data));
        String DateStr = "2017-01-11";
        String tme = "18:10:00";
        Date data = DateUtil.buildDate(DateStr, tme);
        System.out.print(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(data));

    }

    /**
     * @return Date    java.util.Date
     * @Title: getDateOfFirstDayInMonth
     * @Description: 获取当月的第一天
     * @author Illidan
     * @date 2016年5月11日 上午11:21:24
     */
    public static Date getDateOfFirstDayInMonth() {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        String temp = sdf.format(date);
        String firstDayInMoth = "";
        firstDayInMoth = temp + "-01";
        return DateUtil.parseDate(firstDayInMoth);

    }


    /**
     * @return String    字符串
     * @Title: getPlusTime2
     * @Description: 获取指定时间格式为“yyyy-MM-dd HH:mm:ss”的字符的日期
     * @author Illidan
     * @date 2016年5月11日 上午11:23:03
     */
    public static String getPlusTime2(Date date) {

        if (date == null)
            return null;
        try {
            String nowDate = sdfLongTimePlus.format(date);
            return nowDate;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }


    /**
     * @return String    返回类型
     * @Title: getWeekOfDate
     * @Description: 获得指定日期是星期几
     * @author Illidan
     * @date 2016年5月11日 上午11:24:59
     */
    public static String getWeekOfDate(Date dt) {
        String[] weekDays = {"7", "1", "2", "3", "4", "5", "6"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;
        return weekDays[w];
    }

    /**
     * @return Date    返回类型
     * @Title: beforeSomeHour
     * @Description: 指定时间前的hours小时mm分钟
     * @author Illidan
     * @date 2016年5月11日 上午11:25:18
     */
    public static Date beforeSomeHour(Date date, int hours, int mm) {
        try {
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            c.add(Calendar.HOUR, -hours);
            c.add(Calendar.MINUTE, -mm);
            date = c.getTime();
            return date;
        } catch (Exception e1) {
            e1.printStackTrace();
            return null;
        }
    }

    /**
     * 获取指定格式的UTC时间
     *
     * @param simpleDateFormat 指定格式
     * @return 返回字符串类型的当前UTC时间
     */
    public static String getUTC(String simpleDateFormat) {
        SimpleDateFormat df = new SimpleDateFormat(simpleDateFormat);
        Date date = getUTC();
        return df.format(date);
    }

    /**
     * 获取标准的UTC时间。格式为：yyyy-MM-dd'T'HH:mm:ss'Z'
     *
     * @return 返回字符串类型的标准格式的UTC时间
     */
    public static String getStandardUTC() {
        return getUTC("yyyy-MM-dd'T'HH:mm:ss'Z'");
    }

    /**
     * 获取UTC时间
     *
     * @return 返回当前时间的UTC时间，日期类型
     */
    public static Date getUTC() {
        Calendar cal = Calendar.getInstance();
        //取得时间偏移量
        int zoneOffset = cal.get(Calendar.ZONE_OFFSET);
        //取得夏令时差
        int dstOffset = cal.get(Calendar.DST_OFFSET);
        //从本地时间里扣除这些差量，即可以取得UTC时间
        cal.add(Calendar.MILLISECOND, -(zoneOffset + dstOffset));
        return cal.getTime();
    }


    public static Date gStopTime(Date date, Integer addMonth) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        calendar.add(Calendar.MONTH, addMonth);

        return calendar.getTime();
    }

    /**
     * 判断特定时间是否在一个时间范围内
     */
    public static Boolean isInTheTime(Date time, Date starttime, Date endtime) {

        if (time == null || starttime == null || endtime == null) {
            return false;
        }

        if ((time.compareTo(starttime) >= 0) && (time.compareTo(endtime) <= 0)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获取两个时间差
     *
     * @param endDate
     * @param nowDate
     * @return
     */
    public static Long getDatePoor(Date endDate, Date nowDate) {

        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        // long sec = diff % nd % nh % nm / ns;
//		if(day==0){
//			return  hour + ":" + min + ":00";
//		}
//		return day + "天" + hour + ":" + min + ":00";
        return diff;
    }

    /*
     *** 获取时长 s- 开始时间，e - 结束时间
     * 返回小时
     **/
    public static Integer getDtDurationH(Date s, Date e) {
        long courseDuration = e.getTime() - s.getTime();
        //long durationD=courseDuration/(24*60*60*1000); //没跨天，所以不用考虑天数因素
        long durationH = courseDuration / (60 * 60 * 1000);
        return (int) durationH;
    }

    /**
     * 获取当期属于星期几
     */
    public static Integer getWeekByDate(Date date) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int intWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (intWeek == 0) {
            return 7;
        } else {
            return intWeek;
        }
    }

    public static List<Date> dateSplit(Date startDate, Date endDate) {

        Long spi = endDate.getTime() - startDate.getTime();
        Long step = spi / (24 * 60 * 60 * 1000);// 相隔天数

        List<Date> dateList = new ArrayList<Date>();
        dateList.add(startDate);
        for (int i = 1; i <= step; i++) {
            dateList.add(DateUtil.dateAddDays(startDate, i));
        }
        return dateList;
    }


    /**
     * 2017.7.5日上午 8:00 -10:00
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 2017.7.5日上午 8:00 -10:00
     */
    public static String formartContent(Date startTime, Date endTime) {
        String content = new SimpleDateFormat("yyyy.MM.dd a").format(startTime);
        content += new SimpleDateFormat(" hh:mm ").format(startTime) + "-" + new SimpleDateFormat(" hh:mm ").format(endTime);
        return content;
    }

    public static Date Now() {
        return new Date();
    }

    public static Date formatYMD(Date date) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd ");
        return parseDate(df.format(date));
    }

    /**
     * 某个时间之前的时间
     *
     * @param date
     * @param minutes
     * @return
     */
    public static Date getPreDateForMinutes(Date date, Integer minutes) {
        Calendar c = new GregorianCalendar();
        c.setTime(date);//设置参数时间
        c.add(Calendar.MINUTE, (0 - minutes));
        return c.getTime();
    }

    /**
     * 某个时间之后的时间
     *
     * @param date
     * @param minutes
     * @return
     */
    public static Date getNextDateForMinutes(Date date, Integer minutes) {
        Calendar c = new GregorianCalendar();
        c.setTime(date);//设置参数时间
        c.add(Calendar.MINUTE, (minutes));
        return c.getTime();
    }

    public static Date buildDate(String d, String t) throws ParseException {
        String datetiem = d + " " + t;
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return df.parse(datetiem);
    }

    public static Date buildDate(Long ms) throws Exception {

        Timestamp timestamp = new Timestamp(ms);
        Date date = new Date(timestamp.getTime());
        ;
        return date;

    }

    /**
     * 获取当前时间的时间戳
     *
     * @return int值
     * @author lmc 2015年11月6日
     */
    public static int getCurrentTimeIntValue() {
        return (int) (System.currentTimeMillis() / 1000);

    }

    public static int addDaysTimeStamp(int days) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(Calendar.DATE, days);
        return (int) (cal.getTimeInMillis() / 1000);
    }

    public static int addDaysTimeStamp(int days, Integer baseMs) throws Exception {
        long timeStamp = Long.valueOf(baseMs.toString());
        timeStamp = timeStamp * 1000;
        Date startDate = buildDate(timeStamp);
        Calendar cal = Calendar.getInstance();
        cal.setTime(startDate);
        cal.add(Calendar.DATE, days);
        return (int) (cal.getTimeInMillis() / 1000);
    }

    public static Calendar getCalByTimestamp(Integer ms) {
        try {
            long timeStamp = Long.valueOf(ms.toString());
            timeStamp = timeStamp * 1000;
            Date startDate = buildDate(timeStamp);
            Calendar cal = Calendar.getInstance();
            cal.setTime(startDate);
            return cal;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

    }


    public static int getStartTimeStamp() {
        Calendar todayStart = Calendar.getInstance();
        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        long time = todayStart.getTimeInMillis()/1000;
        return (int)time;
    }



    public static int getEndTimeStamp() {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        long time = todayEnd.getTimeInMillis() / 1000;
        return (int) time;
    }

    public static int getStartTimeStamp(Date date) {
        Calendar todayStart = Calendar.getInstance();
        todayStart.setTime(date);
        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        long time = todayStart.getTimeInMillis()/1000;
        return (int)time;
    }



    public static int getEndTimeStamp(Date date) {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.setTime(date);
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        long time = todayEnd.getTimeInMillis() / 1000;
        return (int) time;
    }
    
    
    public static int getPreTime(int s) {
        Calendar todayEnd = Calendar.getInstance();

        todayEnd.set(Calendar.SECOND, 0-s);

        long time = todayEnd.getTimeInMillis() / 1000;
        return (int) time;
    }
}
